/**
 * ============用户数据模型模块开始===========
 * 用户数据模型 - User Data Model
 * 
 * 功能说明：
 * - 提供用户数据的增删改查操作
 * - 封装数据库访问逻辑，提供统一的数据接口
 * - 处理用户密码的加密和验证
 * - 管理用户的基本信息和状态
 * - 支持多种查询方式（手机号、邮箱、ID）
 * 
 * 依赖模块：
 * - bcryptjs: 用于密码加密和验证的安全库
 * - database: 本地JSON数据库实例，提供数据持久化
 * 
 * 数据结构：
 * User对象包含以下字段：
 * - id: 用户唯一标识符
 * - phone: 手机号（可选，用于手机号登录）
 * - email: 邮箱地址（可选，用于邮箱登录）
 * - password: 加密后的密码
 * - nickname: 用户昵称
 * - avatar: 头像URL
 * - gender: 性别
 * - birthDate: 出生日期
 * - birthTime: 出生时间
 * - createdAt: 创建时间
 * - updatedAt: 更新时间
 * - lastLoginAt: 最后登录时间
 * - isActive: 账户是否激活
 * 
 * 安全特性：
 * - 密码使用bcrypt进行哈希加密
 * - 支持密码强度验证
 * - 防止SQL注入（使用参数化查询）
 * - 敏感信息过滤（返回用户信息时排除密码）
 * 
 * 应用场景：
 * - 用户注册和登录系统
 * - 用户信息管理
 * - 身份验证和授权
 * - 用户画像分析
 * 
 * Provides comprehensive user data management with security features
 */

// 导入必要的依赖包 - Import necessary dependencies
import bcrypt from "bcryptjs";           // 密码加密库 - Password encryption library
import { db } from "../data/database.js"; // 数据库实例 - Database instance

/**
 * 用户数据模型类 - User Data Model Class
 * 
 * 该模型封装了所有与用户数据相关的数据库操作
 * 提供了完整的CRUD功能和业务逻辑处理
 * 
 * 设计原则：
 * - 单一职责：只处理用户数据相关的操作
 * - 数据安全：所有密码操作都经过加密处理
 * - 接口统一：提供一致的异步接口
 * - 错误处理：完善的异常处理和日志记录
 * - 性能优化：合理的数据查询和缓存策略
 */
export const UserModel = {
  /**
   * ============根据手机号查找用户功能开始===========
   * 根据手机号查找用户
   * Find user by phone number
   * 
   * @param {string} phone - 手机号，格式：11位数字
   * @returns {Promise<Object|null>} 用户对象或null（如果未找到）
   * @throws {Error} 当数据库操作失败时抛出异常
   * 
   * 功能说明：
   * - 在数据库中查找指定手机号的用户
   * - 支持完全匹配查询
   * - 返回完整的用户信息（不包含密码）
   * - 自动处理数据库读取和错误处理
   * 
   * 使用场景：
   * - 用户登录验证
   * - 手机号重复性检查
   * - 找回密码功能
   * - 用户信息查询
   * 
   * 使用示例：
   * const user = await UserModel.findByPhone('13800138000');
   * if (user) {
   *   console.log('用户存在:', user.nickname);
   * } else {
   *   console.log('用户不存在');
   * }
   * 
   * 异常处理：
   * - 数据库读取失败：网络问题或文件权限问题
   * - 参数验证失败：手机号格式不正确
   * 
   * 性能考虑：
   * - 使用数组的find方法进行线性查找
   * - 对于大量用户数据，建议添加索引或使用专业数据库
   * - 查询结果可以考虑缓存以提高性能
   */
  async findByPhone(phone) {
    try {
      // 第一步：参数验证 - Step 1: Parameter validation
      if (!phone) {
        throw new Error('手机号不能为空 - Phone number cannot be empty');
      }
      
      // 验证手机号格式 - Validate phone number format
      const phoneRegex = /^1[3-9]\d{9}$/;
      if (!phoneRegex.test(phone)) {
        throw new Error('手机号格式不正确 - Invalid phone number format');
      }
      
      // 第二步：读取最新的数据库数据 - Step 2: Read latest database data
      // 确保获取到最新的数据状态，避免数据不一致
      await db.read();
      
      // 第三步：在用户数组中查找匹配的手机号 - Step 3: Find matching phone number in users array
      // 使用find方法进行精确匹配查找
      const user = db.data.users.find((user) => user.phone === phone);
      
      // 第四步：返回结果处理 - Step 4: Process return result
      if (user) {
        // 返回用户信息时排除敏感信息（密码）
        const { password, ...userWithoutPassword } = user;
        return userWithoutPassword;
      }
      
      return null; // 未找到用户时返回null
      
    } catch (error) {
      // 第五步：错误处理 - Step 5: Error handling
      console.error('根据手机号查找用户失败 - Failed to find user by phone:', error);
      throw new Error(`查找用户失败: ${error.message}`);
    }
  },

  /**
   * ============根据邮箱查找用户功能开始===========
   * 根据邮箱查找用户
   * Find user by email address
   * 
   * @param {string} email - 邮箱地址，必须符合邮箱格式
   * @returns {Promise<Object|null>} 用户对象或null（如果未找到）
   * @throws {Error} 当数据库操作失败时抛出异常
   * 
   * 功能说明：
   * - 在数据库中查找指定邮箱的用户
   * - 支持邮箱格式验证
   * - 不区分大小写的邮箱匹配
   * - 返回完整的用户信息（不包含密码）
   * 
   * 使用场景：
   * - 邮箱登录验证
   * - 邮箱重复性检查
   * - 邮件发送前的用户验证
   * - 用户信息查询
   * 
   * 使用示例：
   * const user = await UserModel.findByEmail('user@example.com');
   * if (user) {
   *   console.log('找到用户:', user.nickname);
   * }
   * 
   * 异常处理：
   * - 邮箱格式验证失败
   * - 数据库读取异常
   * 
   * 安全考虑：
   * - 邮箱地址转换为小写进行比较，避免大小写敏感问题
   * - 返回结果中排除密码等敏感信息
   */
  async findByEmail(email) {
    try {
      // 第一步：参数验证 - Step 1: Parameter validation
      if (!email) {
        throw new Error('邮箱地址不能为空 - Email address cannot be empty');
      }
      
      // 验证邮箱格式 - Validate email format
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        throw new Error('邮箱格式不正确 - Invalid email format');
      }
      
      // 第二步：读取最新的数据库数据 - Step 2: Read latest database data
      await db.read();
      
      // 第三步：在用户数组中查找匹配的邮箱 - Step 3: Find matching email in users array
      // 转换为小写进行比较，确保不区分大小写
      const normalizedEmail = email.toLowerCase();
      const user = db.data.users.find((user) => 
        user.email && user.email.toLowerCase() === normalizedEmail
      );
      
      // 第四步：返回结果处理 - Step 4: Process return result
      if (user) {
        // 返回用户信息时排除敏感信息（密码）
        const { password, ...userWithoutPassword } = user;
        return userWithoutPassword;
      }
      
      return null; // 未找到用户时返回null
      
    } catch (error) {
      // 第五步：错误处理 - Step 5: Error handling
      console.error('根据邮箱查找用户失败 - Failed to find user by email:', error);
      throw new Error(`查找用户失败: ${error.message}`);
    }
  },

  /**
   * ============根据ID查找用户功能开始===========
   * 根据用户ID查找用户
   * Find user by user ID
   * 
   * @param {string} id - 用户ID，唯一标识符
   * @returns {Promise<Object|null>} 用户对象或null（如果未找到）
   * @throws {Error} 当数据库操作失败时抛出异常
   * 
   * 功能说明：
   * - 根据用户的唯一ID查找用户信息
   * - 这是最快速和准确的用户查找方式
   * - 通常用于已认证用户的信息获取
   * - 返回完整的用户信息（不包含密码）
   * 
   * 使用场景：
   * - JWT token验证后获取用户信息
   * - 用户信息更新前的数据获取
   * - 用户权限验证
   * - 用户资料页面数据加载
   * 
   * 使用示例：
   * const user = await UserModel.findById('user123');
   * if (user) {
   *   console.log('用户信息:', user);
   * }
   * 
   * 性能优势：
   * - ID查找通常是最高效的查询方式
   * - 可以考虑添加内存缓存进一步提升性能
   */
  async findById(id) {
    try {
      // 第一步：参数验证 - Step 1: Parameter validation
      if (!id) {
        throw new Error('用户ID不能为空 - User ID cannot be empty');
      }
      
      // 第二步：读取最新的数据库数据 - Step 2: Read latest database data
      await db.read();
      
      // 第三步：在用户数组中查找匹配的ID - Step 3: Find matching ID in users array
      const user = db.data.users.find((user) => user.id === id);
      
      // 第四步：返回结果处理 - Step 4: Process return result
      if (user) {
        // 返回用户信息时排除敏感信息（密码）
        const { password, ...userWithoutPassword } = user;
        return userWithoutPassword;
      }
      
      return null; // 未找到用户时返回null
      
    } catch (error) {
      // 第五步：错误处理 - Step 5: Error handling
      console.error('根据ID查找用户失败 - Failed to find user by ID:', error);
      throw new Error(`查找用户失败: ${error.message}`);
    }
  },

  /**
   * ============创建新用户功能开始===========
   * 创建新用户
   * Create new user
   * 
   * @param {Object} userData - 用户数据对象
   * @param {string} userData.phone - 手机号（可选）
   * @param {string} userData.email - 邮箱地址（可选）
   * @param {string} userData.password - 明文密码
   * @param {string} userData.nickname - 用户昵称
   * @param {string} userData.gender - 性别
   * @param {string} userData.birthDate - 出生日期
   * @param {string} userData.birthTime - 出生时间
   * @returns {Promise<Object>} 创建的用户对象（不包含密码）
   * @throws {Error} 当创建失败时抛出异常
   * 
   * 功能说明：
   * - 创建新的用户记录
   * - 自动生成唯一的用户ID
   * - 对密码进行bcrypt加密处理
   * - 设置创建时间和更新时间
   * - 验证必要字段的完整性
   * - 检查手机号和邮箱的唯一性
   * 
   * 安全特性：
   * - 密码使用bcrypt进行哈希加密（salt rounds: 10）
   * - 验证手机号和邮箱的唯一性，防止重复注册
   * - 输入数据验证和清理
   * - 敏感信息过滤
   * 
   * 使用示例：
   * const newUser = await UserModel.create({
   *   phone: '13800138000',
   *   email: 'user@example.com',
   *   password: 'securePassword123',
   *   nickname: '用户昵称',
   *   gender: 'male',
   *   birthDate: '1990-01-01',
   *   birthTime: '08:00'
   * });
   * 
   * 异常处理：
   * - 必要字段缺失
   * - 手机号或邮箱已存在
   * - 密码加密失败
   * - 数据库写入失败
   */
  async create(userData) {
    try {
      // 第一步：参数验证 - Step 1: Parameter validation
      if (!userData) {
        throw new Error('用户数据不能为空 - User data cannot be empty');
      }
      
      // 验证必要字段 - Validate required fields
      if (!userData.password) {
        throw new Error('密码不能为空 - Password cannot be empty');
      }
      
      if (!userData.nickname) {
        throw new Error('昵称不能为空 - Nickname cannot be empty');
      }
      
      // 至少需要手机号或邮箱其中之一 - At least phone or email is required
      if (!userData.phone && !userData.email) {
        throw new Error('手机号或邮箱至少需要提供一个 - Phone or email is required');
      }
      
      // 第二步：检查用户是否已存在 - Step 2: Check if user already exists
      await db.read();
      
      // 检查手机号是否已存在 - Check if phone number already exists
      if (userData.phone) {
        const existingUserByPhone = db.data.users.find(user => user.phone === userData.phone);
        if (existingUserByPhone) {
          throw new Error('该手机号已被注册 - Phone number already registered');
        }
      }
      
      // 检查邮箱是否已存在 - Check if email already exists
      if (userData.email) {
        const normalizedEmail = userData.email.toLowerCase();
        const existingUserByEmail = db.data.users.find(user => 
          user.email && user.email.toLowerCase() === normalizedEmail
        );
        if (existingUserByEmail) {
          throw new Error('该邮箱已被注册 - Email already registered');
        }
      }
      
      // 第三步：密码加密 - Step 3: Password encryption
      // 使用bcrypt对密码进行哈希加密，salt rounds设置为10
      // 这是安全性和性能的平衡选择
      const saltRounds = 10;
      const hashedPassword = await bcrypt.hash(userData.password, saltRounds);
      
      // 第四步：生成用户ID和时间戳 - Step 4: Generate user ID and timestamps
      const userId = this.generateUserId();
      const currentTime = new Date().toISOString();
      
      // 第五步：构建用户对象 - Step 5: Build user object
      const newUser = {
        id: userId,
        phone: userData.phone || null,
        email: userData.email ? userData.email.toLowerCase() : null,
        password: hashedPassword,
        nickname: userData.nickname,
        avatar: userData.avatar || null,
        gender: userData.gender || null,
        birthDate: userData.birthDate || null,
        birthTime: userData.birthTime || null,
        createdAt: currentTime,
        updatedAt: currentTime,
        lastLoginAt: null,
        isActive: true
      };
      
      // 第六步：保存到数据库 - Step 6: Save to database
      db.data.users.push(newUser);
      await db.write();
      
      // 第七步：返回用户信息（排除密码） - Step 7: Return user info (exclude password)
      const { password, ...userWithoutPassword } = newUser;
      
      console.log('用户创建成功 - User created successfully:', userId);
      return userWithoutPassword;
      
    } catch (error) {
      // 第八步：错误处理 - Step 8: Error handling
      console.error('创建用户失败 - Failed to create user:', error);
      throw new Error(`创建用户失败: ${error.message}`);
    }
  },

  /**
   * ============更新用户最后登录时间功能开始===========
   * 更新用户最后登录时间
   * Update user's last login time
   * 
   * @param {string} userId - 用户ID
   * @returns {Promise<boolean>} 更新是否成功
   * @throws {Error} 当更新失败时抛出异常
   * 
   * 功能说明：
   * - 更新指定用户的最后登录时间
   * - 用于跟踪用户活跃度
   * - 支持用户行为分析
   * - 自动设置为当前时间
   * 
   * 使用场景：
   * - 用户登录成功后调用
   * - 用户活跃度统计
   * - 安全审计日志
   * 
   * 使用示例：
   * const success = await UserModel.updateLastLogin('user123');
   * if (success) {
   *   console.log('登录时间更新成功');
   * }
   */
  async updateLastLogin(userId) {
    try {
      // 第一步：参数验证 - Step 1: Parameter validation
      if (!userId) {
        throw new Error('用户ID不能为空 - User ID cannot be empty');
      }
      
      // 第二步：读取数据库 - Step 2: Read database
      await db.read();
      
      // 第三步：查找用户 - Step 3: Find user
      const userIndex = db.data.users.findIndex(user => user.id === userId);
      if (userIndex === -1) {
        throw new Error('用户不存在 - User not found');
      }
      
      // 第四步：更新最后登录时间 - Step 4: Update last login time
      const currentTime = new Date().toISOString();
      db.data.users[userIndex].lastLoginAt = currentTime;
      db.data.users[userIndex].updatedAt = currentTime;
      
      // 第五步：保存到数据库 - Step 5: Save to database
      await db.write();
      
      console.log('用户最后登录时间更新成功 - Last login time updated successfully:', userId);
      return true;
      
    } catch (error) {
      // 第六步：错误处理 - Step 6: Error handling
      console.error('更新最后登录时间失败 - Failed to update last login time:', error);
      throw new Error(`更新登录时间失败: ${error.message}`);
    }
  },

  /**
   * ============生成用户ID功能开始===========
   * 生成唯一的用户ID
   * Generate unique user ID
   * 
   * @returns {string} 唯一的用户ID
   * 
   * 功能说明：
   * - 生成基于时间戳和随机数的唯一ID
   * - 确保ID的唯一性和不可预测性
   * - 使用前缀'user_'便于识别
   * 
   * ID格式：user_[timestamp]_[random]
   * 例如：user_1640995200000_abc123
   */
  generateUserId() {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    return `user_${timestamp}_${random}`;
  },

  /**
   * ============验证密码功能开始===========
   * 验证用户密码
   * Verify user password
   * 
   * @param {string} plainPassword - 明文密码
   * @param {string} hashedPassword - 加密后的密码
   * @returns {Promise<boolean>} 密码是否匹配
   * 
   * 功能说明：
   * - 使用bcrypt验证明文密码与哈希密码是否匹配
   * - 安全的密码验证方式
   * - 防止时序攻击
   * 
   * 使用示例：
   * const isValid = await UserModel.verifyPassword('userInput', user.password);
   * if (isValid) {
   *   console.log('密码正确');
   * }
   */
  async verifyPassword(plainPassword, hashedPassword) {
    try {
      return await bcrypt.compare(plainPassword, hashedPassword);
    } catch (error) {
      console.error('密码验证失败 - Password verification failed:', error);
      return false;
    }
  }
};
